package cn.seaboot.admin.mybatis;

import cn.seaboot.admin.mvc.Pagination;
import cn.seaboot.admin.mvc.mask.ReturnValueDesensitization;
import cn.seaboot.admin.mvc.response.MybatisOrderMapper;
import cn.seaboot.commons.lang.Warning;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import javax.annotation.Resource;

/**
 * mybatis 自定义配置
 *
 * @author Mr.css
 * @version 2023-06-28 14:58
 * @see MybatisAutoConfiguration
 */
@EnableConfigurationProperties({PageHelperProperties.class, SeaMybatisProperties.class})
@org.springframework.context.annotation.Configuration
public class MybatisStarter implements ConfigurationCustomizer {
    private final Logger logger = LoggerFactory.getLogger(MybatisStarter.class);

    @Resource
    private PageHelperProperties pageHelperProperties;

    @Resource
    private SeaMybatisProperties seaMybatisProperties;

    @Resource
    private ReturnValueDesensitization returnValueDesensitization;

    @Override
    public void customize(Configuration configuration) {
        logger.debug("[Mybatis] using local setting, database-id is: {}", configuration.getDatabaseId());

        {
            // using page helper
            logger.debug("[Mybatis] page-helper：{}", this.pageHelperProperties);
            Interceptor interceptor = new PageInterceptor();
            interceptor.setProperties(this.pageHelperProperties.getProperties());
            if (!containsInterceptor(configuration, interceptor)) {
                configuration.addInterceptor(interceptor);
            }
            MybatisOrderMapper mapper = new MybatisOrderMapper(configuration);
            // using page helper
            logger.debug("[Mybatis] page-helper using mapper：{}", MybatisOrderMapper.class.getName());
            Pagination.setOrderMapper(mapper);
        }
        {
            if(seaMybatisProperties.isUsingDesensitize()){
                // using desensitize
                logger.debug("[Mybatis] using desensitization：{}", DesensitizationInterceptor.class);
                Interceptor interceptor = new DesensitizationInterceptor(returnValueDesensitization);
                if (!containsInterceptor(configuration, interceptor)) {
                    configuration.addInterceptor(interceptor);
                }
            }
        }
    }

    /**
     * 是否已经存在相同的拦截器
     *
     * @param configuration -
     * @param interceptor   -
     * @return -
     */
    @SuppressWarnings(Warning.ALL)
    private boolean containsInterceptor(org.apache.ibatis.session.Configuration configuration, Interceptor interceptor) {
        try {
            return configuration.getInterceptors().stream().anyMatch(config -> interceptor.getClass().isAssignableFrom(config.getClass()));
        } catch (Exception e) {
            return false;
        }
    }
}
